package worker

import (
	"xmediaEmu/pkg/log"
)

// startGameHandler starts a game if roomID is given, if not create new room
// 创建room。游戏逻辑保存在room里.
// 一个room可以包含多个sessions.
func (h *Handler) startGameHandler(gameName string, bUseUnixSocket bool, existedRoomID string, playerIndex int, sess *Session) *Room {
	log.Logger.Infof("Loading game: %v\n", gameName)
	// If we are connecting to coordinator, request corresponding serverID based on roomID
	// TODO: check if existedRoomID is in the current server
	room := h.getRoom(existedRoomID)
	// If room is not running
	if room == nil {
		log.Logger.Info("Create Room from local ", room, " with ID: ", existedRoomID)
		// Create new room and update player index
		room = h.createNewRoom(gameName, bUseUnixSocket, existedRoomID)
		room.UpdatePlayerIndex(sess.peerconnection, playerIndex)

		// Wait for done signal from room
		// room关闭给打开room的创建者发送消息并且更新handlers.
		// TODO: 如何避免实例吊死？
		// 主动关闭场景
		go func() {
			// room没有client时关闭，通知client端关闭了.
			<-room.Done
			h.detachRoom(room.ID)
			// send signal to coordinator that the room is closed, then client will remove that room
			// no session left, remove it.
			// 如果是主动关闭这一步必须(比如和IT层的远端连接关闭了),等待本端连接被释放.
			if h.oClient != nil {
				//
				// h.oClient.Send(entity.CloseRoomPacket(room.ID), nil)
				// 此时ws连接需要关闭了
				// 如何保证ws连接和room一一对应资源.
				// h.wsConn.Close()
			}
		}()
	}

	// Attach peerconnection to room. If PC is already in room, don't detach
	log.Logger.Infof("startGameHandler is already in room:%v", room.InRoom(sess))
	if !room.InRoom(sess) {
		room.AddConnectionToRoom(sess)
	}

	// Register room to coordinator if we are connecting to coordinator
	//if room != nil && h.oClient != nil {
	//	// 直接在response里一条消息返回给client.
	//	// h.oClient.Send(entity.RegisterRoomPacket(room.ID), nil)
	//}

	// 简单化处理这里直接返回room.
	return room
}

// detachPeerConn detaches a peerconnection from the current room.
func (h *Handler) detachPeerConn(pc *Session) {
	log.Logger.Info("[worker] closing peer connection")
	gameRoom := pc.room
	if gameRoom == nil || gameRoom.IsEmpty() {
		return
	}
	gameRoom.RemoveSession(pc)
	if gameRoom.IsEmpty() {
		log.Logger.Info("[worker] closing an empty room")
		gameRoom.Close()
	}
}
